import axios from "axios";
import { message } from "ant-design-vue";
import router from "@/router/index";
import { getToken } from "@/utils/auth"; // get token from cookie
import defaultCustomConfig from "@/settings/requestSetting";

// 取消重复请求
// 请求存储的队列
const pendingMap = new Map();

// 生成每个请求唯一的键
function getPendingKey(config) {
  let { url, method, params, data } = config;
  if (typeof data === "string") data = JSON.parse(data); // response里面返回的config.data是个字符串对象
  return [url, method, JSON.stringify(params), JSON.stringify(data)].join("&");
}

// 储存每个请求唯一值, 也就是cancel()方法, 用于取消请求
function addPending(config) {
  const pendingKey = getPendingKey(config);
  config.cancelToken =
    config.cancelToken ||
    new axios.CancelToken((cancel) => {
      if (!pendingMap.has(pendingKey)) {
        pendingMap.set(pendingKey, cancel);
      }
    });
}

// 删除重复的请求
function removePending(config) {
  const pendingKey = getPendingKey(config);
  if (pendingMap.has(pendingKey)) {
    const cancelToken = pendingMap.get(pendingKey);
    cancelToken(pendingKey);
    pendingMap.delete(pendingKey);
  }
}

// loading动画
const LoadingInstance = {
  // 保存Loading实例
  target: null,
  count: 0,
};

// 关闭Loading层实例
function closeLoading(_options) {
  if (_options.loading && LoadingInstance.count > 0) LoadingInstance.count--;
  if (LoadingInstance.count === 0) {
    LoadingInstance.target();
  }
}

/**
 *
 * @param {*} config axios配置
 * @param {*} customConfig 外部配置
 * @param {*} loadingConfig loading配置
 */
export function request(
  config,
  customConfig,
  loadingConfig = { content: "loading", duration: 0 }
) {
  // 配置新建一个 axios 实例
  const service = axios.create({
    baseURL: import.meta.env.VITE_API_URL,
    timeout: 20000,
    headers: { "Content-Type": "application/json" },
  });

  // 合并外部配置与自定义默认配置
  let customOptions = {
    ...defaultCustomConfig,
    ...customConfig,
  };

  // 添加请求拦截器
  service.interceptors.request.use(
    (config) => {
      removePending(config);
      customOptions.cancelDuplicateRequest && addPending(config);
      // 创建loading实例
      if (customOptions.loading) {
        LoadingInstance.count++;
        if (LoadingInstance.count === 1) {
          LoadingInstance.target = message.loading(loadingConfig);
        }
      }
      // 添加token请求头
      const token = getToken();
      if (token) {
        config.headers.authorization = token;
      }
      return config;
    },
    (error) => {
      // 对请求错误做些什么
      return Promise.reject(error);
    }
  );

  // 添加响应拦截器
  service.interceptors.response.use(
    (response) => {
      // 对响应数据做点什么
      removePending(response.config);
      // 关闭loading
      customOptions.loading && closeLoading(customOptions);
      const { code, msg } = response.data;
      if (code && code !== 0) {
        // `token` 过期或者账号已在别处登录
        if (code === 401 || code === 403) {
          // 清除浏览器全部临时缓存
          router.push("/login"); // 去登录页面
        }
        message.error(msg);
      } else {
        const requestType = response.config.method.toLowerCase();
        const successMsg = msg || customOptions.msg;
        const { showSuccessMsg, dataSimplify } = customOptions;
        if (["put", "delete"].includes(requestType)) {
          if (
            typeof showSuccessMsg === "undefined" ||
            (showSuccessMsg && successMsg)
          ) {
            message.success(successMsg);
          }
        } else {
          if (showSuccessMsg && successMsg) {
            message.success(successMsg);
          }
        }
        return dataSimplify ? response.data : response;
      }
    },
    (error) => {
      // 对响应错误做点什么
      error.config && removePending(error.config);
      // 关闭loading
      customOptions.loading && closeLoading(customOptions);
      message.error("请求服务异常，请刷新后重试");
      return Promise.reject(error);
    }
  );

  return service(config);
}
